class BundlesController < AuthorizedController
  before_filter :login_required
  before_filter :load_bundle, :only => [:show, :edit, :update, :destroy, :share]

  # Main page for comparing all bundles of the logged-in user's portfolio
  def index
    @bundles = current_user.bundles.find(:all)
    session[:compared_bundles] ||= []
    @compared_bundles = @bundles.select { |b| session[:compared_bundles].include? b.id }.sort_by { |b| session[:compared_bundles].index(b.id) }
  end

  # Bundle summary page, to compare a bundle against a portfolio
  def show
    session[:active_bundle_id] = @bundle.to_param
  end
  
  # Set the active_bundle_id and send to posting editor
  def switch_to
    session[:active_bundle_id] = params[:bundle][:id] if params[:bundle]
    session[:active_bundle_id] = params[:bundle_id] if params[:bundle_id]
    redirect_to postings_url
  end
  
  def new
    @bundle = Bundle.new
  end

  # Creates a bundle for the current user from the submitted form. Redirects to the new bundle.
  def create
    @new_bundle = current_user.bundles.build(params[:bundle])

    if @new_bundle.save
      set_flash :success => 'Bundle was successfully created.'
      session[:active_bundle_id] = @new_bundle.to_param
      respond_to do |wants|
        wants.html { redirect_to(postings_url) }
        wants.js   { render :status => 302, :text => postings_url }
      end
    else
      respond_to do |wants|
        @bundle = @new_bundle
        wants.html { render :action => "new" }
        wants.js   { render :status => 500, :partial => "bundles/new_bundle.html.erb" }
      end
    end
  end
  
  def edit
    if ["notes", "title"].include?(params[:attribute])
      render :text => @bundle.read_attribute(params[:attribute].to_sym) || ""
    else
      render :status => 500, :text => "error: #{params[:attribute]} is not a valid field to request"
    end
  end

  # Updates a Bundle with the passed attributes. If the update fails, redirect
  def update
    attributes = params[:bundle].slice(:notes, :title)
    updated = @bundle.update_attributes(attributes)
    respond_to do |wants|
      wants.html do
        if updated
          set_flash :success => 'Bundle was successfully updated.'
          redirect_back_or_default(bundles_url)
        else
          set_flash :error => 'There was a problem saving your changes. Please check the form for errors.'
          render :action => "edit"
        end
      end
      wants.js do
        # We are doing an inline update, grab the first passed parameter only
        attribute = attributes.to_a.first.first # e.g. get [:title, 'bundle title'] and return :title
        @bundle.reload unless @bundle.valid?
        if updated
          render :json => @bundle.read_attribute(attribute).to_s
        else
          head 500
        end
      end
    end
  end
  
  # Removes a bundle from a user's portfolio
  def destroy
    @bundle.destroy
    redirect_to(bundles_url)
  end
  
  # Displays the share form when the HTTP verb is GET. Sends an email to params[:email] when POST.
  def share
    head 500 and return unless params[:email]
    Notification.deliver_share(accept_bundle_url(:bundle_key => @bundle.share_key), @bundle, params[:message], params[:email])
    respond_to do |wants|
      wants.js { head :ok }
      wants.html { redirect_back_or_default(postings_url) }
    end
  end

  # Accept a shared bundle by its opaque id
  def accept
    @bundle_to_copy = Bundle.find_by_share_key(params[:bundle_key])
    @bundle = Bundle.create_from_shared(@bundle_to_copy, current_user)
    unless @bundle.new_record?
      set_flash :success => "You have successfully received the Bundle: #{@bundle.title}"
      redirect_to(postings_url(:bundle_id => @bundle))
    else
      set_flash :error => "Sorry, there was a problem receiving that Bundle: #{@bundle.errors.full_messages}"
      redirect_to(bundles_url)
    end
  end
  
  # AJAX action to add a bundle to compare on the #index page
  def add
    @bundle = current_user.bundles.find(params[:id].split(/_/).last)

    # Add the compared bundle to the session for drag and drop. Allow up to three bundles.
    session[:compared_bundles] ||= []
    session[:compared_bundles].unshift @bundle.id unless session[:compared_bundles].include?(@bundle.id)
    session[:compared_bundles].pop if session[:compared_bundles].length > 3
    
    render :partial => 'compare_bundle', :collection => Bundle.find(:all, :conditions => { :id => session[:compared_bundles] }, :order => "FIELD(id, #{session[:compared_bundles].join(',')})")
  end
  
  # AJAX action to remove a bundle from the comparison area on the #index page
  def remove
    @bundle = current_user.bundles.find(params[:id].split("_bundle_").last)
    session[:compared_bundles] -= [@bundle.id]
    
    if session[:compared_bundles].blank?
      head :ok
    else
      render :partial => 'compare_bundle', :collection => Bundle.find(:all, :conditions => { :id => session[:compared_bundles] }, :order => "FIELD(id, #{session[:compared_bundles].join(',')})")
    end
  end
  
  private
  
  def load_bundle
    @bundle = current_user.bundles.find(params[:id])
  end
end
